﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Linq;
using System.Linq;
using System.Text;

namespace MSAS.FrontEnd.DL
{
    /// <summary>
    /// Cache lookup tables
    /// </summary>
    public class DBCache : MSAS.FrontEnd.DL.ICache
    {
        /// <summary>
        /// Store the list of ObjectExpiration populated at the construction of the cache
        /// </summary>
        private static List<ObjectExpiration> objectExpiration;

        /// <summary>
        /// Store a singleton of the DBCache created with the private ctor
        /// </summary>
        private static DBCache _instance = new DBCache();

        /// <summary>
        /// Create a single instance of the cache
        /// </summary>
        static DBCache()
        {
            try
            {
                using (ServiceDataContext db = new ServiceDataContext())
                {
                    objectExpiration = db.ObjectExpirations.ToList();
                }
            }
            catch (Exception ex)
            {
                throw new ApplicationException("Failed to connect to the database to get cache times." +
                    "Please check the database configuration.", 
                    ex);
            }
        }

        /// <summary>
        /// Method to return the static instance constructed by the singleton
        /// of the database cache
        /// </summary>
        /// <returns></returns>
        public static ICache GetInstance()
        {
            return _instance;
        }

        /// <summary>
        /// Get the server expiration time in minutes from the cache
        /// </summary>
        /// <param name="objectTypeId"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public int GetServerExpirationTime(int objectTypeId, short index)
        {
            return objectExpiration.Single(
                i => i.ObjectTypeId == objectTypeId && i.CacheIndex == index
                ).ServerCacheTime;
        }

        /// <summary>
        /// Get the client expiration time in minutes from the cache
        /// </summary>
        /// <param name="objectTypeId"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public int GetClientExpirationTime(int objectTypeId, short index)
        {
            return objectExpiration.Single(
                i => i.ObjectTypeId == objectTypeId && i.CacheIndex == index
                ).ClientCacheTime;
        }

        /// <summary>
        /// Get the server cache index for the time supplied in minutes
        /// </summary>
        /// <param name="objectTypeId"></param>
        /// <param name="time"></param>
        /// <returns></returns>
        public byte GetServerExpirationIndex(int objectTypeId, int time)
        {
            return (byte) objectExpiration.Single(
                i => i.ObjectTypeId == objectTypeId && i.ServerCacheTime == time
                ).CacheIndex;
        }

        /// <summary>
        /// Get the client cache index for the time supplied in minutes
        /// </summary>
        /// <param name="objectTypeId"></param>
        /// <param name="time"></param>
        /// <returns></returns>
        public byte GetClientExpirationIndex(int objectTypeId, int time)
        {
            return (byte) objectExpiration.Single(
                i => i.ObjectTypeId == objectTypeId && i.ClientCacheTime == time
                ).CacheIndex;
        }
    }
}
